<template>
  <div class="ai-messenger">
    <!-- 顶部控制栏 -->
    <div class="control-bar">
      <div class="provider-selector">
        <label>AI服务:</label>
        <select v-model="selectedProviderId" @change="handleProviderChange">
          <option v-for="provider in availableProviders" :key="provider.id" :value="provider.id">
            {{ provider.name }}
          </option>
        </select>
      </div>

      <div class="controls">
        <button class="btn-config" @click="showConfigPanel = !showConfigPanel">
          <i class="fa fa-cog"></i> 配置
        </button>
        <button class="btn-clear" @click="clearMessages">
          <i class="fa fa-trash"></i> 清空
        </button>
      </div>
    </div>

    <!-- 配置面板 -->
    <div class="config-panel" v-if="showConfigPanel">
      <h3>{{ currentProvider?.name }} 配置</h3>
      <div class="config-form">
        <div class="form-group">
          <label>API密钥:</label>
          <input type="password" v-model="currentConfig.apiKey" placeholder="输入API密钥">
        </div>
        <div class="form-group">
          <label>模型:</label>
          <select v-model="currentConfig.model">
            <option v-for="model in currentProvider?.models || []" :key="model" :value="model">
              {{ model }}
            </option>
          </select>
        </div>
        <div class="form-group">
          <label>温度参数 (0-1):</label>
          <input type="number" v-model="currentConfig.temperature" min="0" max="1" step="0.1">
        </div>
        <button class="btn-save" @click="saveConfig">保存配置</button>
      </div>
    </div>

    <!-- 消息区域 -->
    <div class="message-area">
      <!-- 欢迎消息 -->
      <div v-if="messages.length === 0" class="welcome-message">
        <p>👋 您好！请选择AI服务并开始对话</p>
        <p v-if="!currentConfig.apiKey">提示：需要先配置API密钥才能使用</p>
      </div>

      <!-- 消息列表 -->
      <div v-for="(msg, index) in messages" :key="index" class="message-item"
        :class="{ 'user': msg.role === 'user', 'ai': msg.role === 'ai' }">
        <div class="avatar">
          <i class="fa" :class="msg.role === 'user' ? 'fa-user' : 'fa-robot'"></i>
        </div>
        <div class="content">
          <div class="sender">{{ msg.role === 'user' ? '我' : currentProvider?.name }}</div>
          <div class="text" v-html="formatMessage(msg.content)"></div>
          <div class="time">{{ formatTime(msg.timestamp) }}</div>
        </div>
      </div>

      <!-- 加载状态 -->
      <div v-if="isLoading" class="loading-item">
        <div class="avatar">
          <i class="fa fa-robot"></i>
        </div>
        <div class="content">
          <div class="typing-indicator">
            <span></span>
            <span></span>
            <span></span>
          </div>
        </div>
      </div>

      <!-- 错误提示 -->
      <div v-if="errorMessage" class="error-message">
        <i class="fa fa-exclamation-circle"></i>
        <span>{{ errorMessage }}</span>
        <button @click="retryLastRequest">重试</button>
      </div>
    </div>

    <!-- 输入区域 -->
    <div class="input-area">
      <textarea v-model="userInput" placeholder="输入消息... (Shift+Enter换行，Enter发送)"
        @keydown.enter.exact.prevent="sendMessage" @keydown.enter.shift="handleShiftEnter"
        :disabled="isLoading || !currentConfig.apiKey"></textarea>
      <button class="send-btn" @click="sendMessage" :disabled="!userInput.trim() || isLoading || !currentConfig.apiKey">
        <i class="fa fa-paper-plane"></i>
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import axios from 'axios';
import DOMPurify from 'dompurify';

// 类型定义
interface Message {
  role: 'user' | 'ai';
  content: string;
  timestamp: number;
}

interface AIProvider {
  id: string;
  name: string;
  models: string[];
  defaultConfig: AIConfig;
  requestAdapter: (config: AIConfig, messages: Message[]) => Promise<string>;
}

interface AIConfig {
  apiKey: string;
  apiUrl?: string;
  model: string;
  temperature: number;
}

interface ChatCompletionResponse {
  choices: {
    message: {
      content: string;
    };
  }[];
}
interface ErnieChatResponse {
  result: string;
}
// 可用的AI服务提供商
const availableProviders: AIProvider[] = [
  {
    id: 'doubao',
    name: '豆包',
    models: ['doubao-pro', 'doubao-lite'],
    defaultConfig: {
      apiKey: '0c2e3de4-290b-4d0b-b395-9c78a412da26',
      apiUrl: 'https://api.doubao.com/chat/completions',
      model: 'doubao-pro',
      temperature: 0.7
    },
    requestAdapter: async (config, messages) => {
      const response = await axios.post<ChatCompletionResponse>(config.apiUrl!, {
        model: config.model,
        messages: messages.map(msg => ({
          role: msg.role,
          content: msg.content
        })),
        temperature: config.temperature
      }, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${config.apiKey}`
        }
      });
      return response.data.choices[0].message.content;
    }
  },
  {
    id: 'openai',
    name: 'OpenAI',
    models: ['gpt-3.5-turbo', 'gpt-4'],
    defaultConfig: {
      apiKey: '',
      apiUrl: 'https://api.openai.com/v1/chat/completions',
      model: 'gpt-3.5-turbo',
      temperature: 0.7
    },
    requestAdapter: async (config, messages) => {
      const response = await axios.post<ChatCompletionResponse>(config.apiUrl!, {
        model: config.model,
        messages: messages.map(msg => ({
          role: msg.role,
          content: msg.content
        })),
        temperature: config.temperature
      }, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${config.apiKey}`
        }
      });
      return response.data.choices[0].message.content;
    }
  },
  {
    id: 'ernie',
    name: '文心一言',
    models: ['ernie-bot', 'ernie-bot-turbo'],
    defaultConfig: {
      apiKey: '',
      apiUrl: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions',
      model: 'ernie-bot',
      temperature: 0.7
    },
    requestAdapter: async (config, messages) => {
      // 文心一言API需要在URL中包含API Key
      const url = `${config.apiUrl}?access_token=${config.apiKey}`;
      const response = await axios.post<ErnieChatResponse>(url, {
        messages: messages.map(msg => ({
          role: msg.role,
          content: msg.content
        })),
        temperature: config.temperature
      }, {
        headers: { 'Content-Type': 'application/json' }
      });
      return response.data.result;
    }
  },
  {
    id: 'deepseek',
    name: 'DeepSeek',
    models: ['deepseek-chat', 'deepseek-coder'],
    defaultConfig: {
      apiKey: 'sk-62eeae1f67084a1e9bd51ed47f0f9c69',
      apiUrl: 'https://api.deepseek.com/v1/chat/completions',
      model: 'deepseek-chat',
      temperature: 0.7
    },
    requestAdapter: async (config, messages) => {
      const response = await axios.post<ChatCompletionResponse>(config.apiUrl!, {
        model: config.model,
        messages: messages.map(msg => ({
          role: msg.role,
          content: msg.content
        })),
        temperature: config.temperature
      }, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${config.apiKey}`
        }
      });
      return response.data.choices[0].message.content;
    }
  },
  {
    id: 'gpt',
    name: 'GPT',
    models: ['gpt-3.5-turbo', 'gpt-4', 'gpt-4-turbo', 'gpt-4o'],
    defaultConfig: {
      apiKey: '',
      apiUrl: 'https://api.openai.com/v1/chat/completions',
      model: 'gpt-3.5-turbo',
      temperature: 0.7
    },
    requestAdapter: async (config, messages) => {
      const response = await axios.post<ChatCompletionResponse>(config.apiUrl!, {
        model: config.model,
        messages: messages.map(msg => ({
          role: msg.role,
          content: msg.content
        })),
        temperature: config.temperature
      }, {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${config.apiKey}`
        }
      });
      return response.data.choices[0].message.content;
    }
  },
];

// 状态管理
const messages = ref<Message[]>([]);
const userInput = ref('');
const isLoading = ref(false);
const errorMessage = ref('');
const showConfigPanel = ref(false);
const selectedProviderId = ref(availableProviders[0].id);
const lastUserMessage = ref<string | null>(null);
const providerConfigs = ref<Record<string, AIConfig>>({});

// 计算属性
const currentProvider = computed(() => {
  return availableProviders.find(p => p.id === selectedProviderId.value);
});

const currentConfig = ref<AIConfig>({ ...availableProviders[0].defaultConfig });

// 初始化
onMounted(() => {
  // 从本地存储加载配置
  const savedConfigs = localStorage.getItem('aiProviderConfigs');
  if (savedConfigs) {
    providerConfigs.value = JSON.parse(savedConfigs);
  }

  // 加载当前提供商配置
  loadCurrentProviderConfig();

  // 从本地存储加载消息历史
  const savedMessages = localStorage.getItem('aiMessages');
  if (savedMessages) {
    messages.value = JSON.parse(savedMessages);
  }

  // 监听消息变化，保存到本地存储
  watch(messages, (newVal) => {
    localStorage.setItem('aiMessages', JSON.stringify(newVal));
    scrollToBottom();
  }, { deep: true });
});

// 加载当前提供商配置
const loadCurrentProviderConfig = () => {
  const provider = currentProvider.value;
  if (!provider) return;

  const savedConfig = providerConfigs.value[provider.id];
  currentConfig.value = savedConfig ? { ...savedConfig } : { ...provider.defaultConfig };
};

// 处理提供商切换
const handleProviderChange = () => {
  showConfigPanel.value = false;
  loadCurrentProviderConfig();
};

// 保存配置
const saveConfig = () => {
  if (!currentProvider.value) return;

  providerConfigs.value[currentProvider.value.id] = { ...currentConfig.value };
  localStorage.setItem('aiProviderConfigs', JSON.stringify(providerConfigs.value));
  showConfigPanel.value = false;

  // 显示保存成功提示
  errorMessage.value = '配置已保存';
  setTimeout(() => errorMessage.value = '', 2000);
};

// 发送消息
const sendMessage = async () => {
  const content = userInput.value.trim();
  if (!content || !currentProvider.value || !currentConfig.value.apiKey) return;

  // 添加用户消息
  const userMsg: Message = {
    role: 'user',
    content,
    timestamp: Date.now()
  };
  messages.value.push(userMsg);
  lastUserMessage.value = content;
  userInput.value = '';
  errorMessage.value = '';

  try {
    isLoading.value = true;

    // 调用当前AI服务
    const aiResponse = await currentProvider.value.requestAdapter(
      currentConfig.value,
      messages.value
    );

    // 添加AI回复
    const aiMsg: Message = {
      role: 'ai',
      content: aiResponse,
      timestamp: Date.now()
    };
    messages.value.push(aiMsg);

  } catch (err: any) {
    console.error('AI请求失败:', err);
    errorMessage.value = err.response?.data?.error?.message || '请求失败，请检查配置';
  } finally {
    isLoading.value = false;
  }
};

// 重试最后一次请求
const retryLastRequest = () => {
  if (lastUserMessage.value) {
    userInput.value = lastUserMessage.value;
    sendMessage();
  }
};

// 清空消息
const clearMessages = () => {
  if (confirm('确定要清空所有对话记录吗？')) {
    messages.value = [];
    localStorage.removeItem('aiMessages');
  }
};

// 处理Shift+Enter换行
const handleShiftEnter = () => {
  userInput.value += '\n';
};

// 格式化时间
const formatTime = (timestamp: number) => {
  const date = new Date(timestamp);
  return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
};

// 格式化消息（支持简单Markdown）
const formatMessage = (content: string) => {
  // 处理换行
  let html = content.replace(/\n/g, '<br>');

  // 处理粗体
  html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');

  // 处理斜体
  html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');

  // 处理代码
  html = html.replace(/`(.*?)`/g, '<code>$1</code>');

  // 净化HTML防止XSS
  return DOMPurify.sanitize(html);
};

// 滚动到底部
const scrollToBottom = () => {
  setTimeout(() => {
    const messageArea = document.querySelector('.message-area');
    if (messageArea) {
      messageArea.scrollTop = messageArea.scrollHeight;
    }
  }, 0);
};
</script>

<style lang="scss" scoped>
$primary: #409eff;
$user-bg: #e6f7ff;
$ai-bg: #f5f7fa;
$text: #303133;
$light-text: #606266;
$border: #e4e7ed;
$radius: 8px;
$shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);

.ai-messenger {
  display: flex;
  flex-direction: column;
  height: 650px;
  border: 1px solid $border;
  border-radius: $radius;
  overflow: hidden;
  box-shadow: $shadow;
}

// 顶部控制栏
.control-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px;
  background-color: #f9f9f9;
  border-bottom: 1px solid $border;

  .provider-selector {
    display: flex;
    align-items: center;
    gap: 8px;

    select {
      padding: 6px 10px;
      border: 1px solid $border;
      border-radius: 4px;
      background-color: white;
    }
  }

  .controls {
    display: flex;
    gap: 10px;
  }

  button {
    padding: 6px 12px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 5px;
    background-color: #f0f0f0;
    transition: background-color 0.2s;

    &:hover {
      background-color: #e0e0e0;
    }
  }

  .btn-config {
    color: $primary;
  }

  .btn-clear {
    color: #f56c6c;
  }
}

// 配置面板
.config-panel {
  padding: 15px 20px;
  background-color: #fafafa;
  border-bottom: 1px solid $border;

  h3 {
    margin: 0 0 15px;
    font-size: 16px;
    color: $text;
  }

  .config-form {
    display: flex;
    flex-direction: column;
    gap: 12px;

    .form-group {
      display: flex;
      flex-direction: column;
      gap: 5px;

      label {
        font-size: 14px;
        color: $light-text;
      }

      input,
      select {
        padding: 8px 10px;
        border: 1px solid $border;
        border-radius: 4px;
        font-size: 14px;

        &:focus {
          outline: none;
          border-color: $primary;
        }
      }
    }

    .btn-save {
      align-self: flex-start;
      padding: 8px 16px;
      background-color: $primary;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;

      &:hover {
        background-color: #66b1ff;
      }
    }
  }
}

// 消息区域
.message-area {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background-color: #fff;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background-color: #ddd;
    border-radius: 3px;
  }
}

// 欢迎消息
.welcome-message {
  text-align: center;
  padding: 30px 0;
  color: $light-text;
  font-size: 14px;

  p {
    margin: 5px 0;
  }
}

// 消息项
.message-item {
  display: flex;
  margin-bottom: 15px;
  max-width: 80%;

  &.user {
    margin-left: auto;
    flex-direction: row-reverse;
  }

  .avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: $primary;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 10px;
    flex-shrink: 0;

    &+.content {
      margin-top: 5px;
    }
  }

  .user .avatar {
    margin-right: 0;
    margin-left: 10px;
    background-color: #67c23a;
  }

  .content {
    background-color: $ai-bg;
    padding: 10px 15px;
    border-radius: $radius;
    position: relative;

    &::before {
      content: '';
      position: absolute;
      left: -8px;
      top: 10px;
      width: 0;
      height: 0;
      border-top: 8px solid transparent;
      border-right: 8px solid $ai-bg;
      border-bottom: 8px solid transparent;
    }
  }

  .user .content {
    background-color: $user-bg;

    &::before {
      left: auto;
      right: -8px;
      border-right: none;
      border-left: 8px solid $user-bg;
    }
  }

  .sender {
    font-size: 12px;
    color: $light-text;
    margin-bottom: 4px;
  }

  .text {
    font-size: 14px;
    line-height: 1.6;
    color: $text;

    code {
      background-color: rgba(0, 0, 0, 0.05);
      padding: 2px 4px;
      border-radius: 3px;
      font-family: monospace;
      font-size: 13px;
    }
  }

  .time {
    font-size: 11px;
    color: #909399;
    margin-top: 5px;
    text-align: right;
  }
}

// 加载状态
.loading-item {
  display: flex;
  margin-bottom: 15px;
  max-width: 80%;

  .avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: $primary;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 10px;
  }

  .content {
    background-color: $ai-bg;
    padding: 15px;
    border-radius: $radius;
  }

  .typing-indicator {
    display: flex;
    gap: 4px;

    span {
      width: 8px;
      height: 8px;
      background-color: #999;
      border-radius: 50%;
      animation: typing 1.4s infinite ease-in-out both;
    }

    span:nth-child(1) {
      animation-delay: -0.32s;
    }

    span:nth-child(2) {
      animation-delay: -0.16s;
    }
  }
}

// 错误消息
.error-message {
  background-color: #fff2f0;
  color: #f56c6c;
  padding: 10px 15px;
  border-radius: $radius;
  margin: 0 0 15px 50px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;

  button {
    margin-left: auto;
    background-color: #f56c6c;
    color: white;
    border: none;
    border-radius: 4px;
    padding: 4px 10px;
    font-size: 12px;
    cursor: pointer;

    &:hover {
      background-color: #f78989;
    }
  }
}

// 输入区域
.input-area {
  display: flex;
  align-items: center;
  padding: 15px;
  border-top: 1px solid $border;
  gap: 10px;

  textarea {
    flex: 1;
    min-height: 60px;
    max-height: 150px;
    padding: 10px 15px;
    border: 1px solid $border;
    border-radius: $radius;
    resize: vertical;
    font-size: 14px;
    outline: none;

    &:focus {
      border-color: $primary;
    }

    &:disabled {
      background-color: #f5f5f5;
      cursor: not-allowed;
    }
  }

  .send-btn {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background-color: $primary;
    color: white;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    &:hover {
      background-color: #66b1ff;
    }

    &:disabled {
      background-color: #a0cfff;
      cursor: not-allowed;
    }
  }
}

// 动画
@keyframes typing {
  0% {
    transform: scale(0);
  }

  40% {
    transform: scale(1);
  }

  80% {
    transform: scale(0);
  }

  100% {
    transform: scale(0);
  }
}

// 响应式
@media (max-width: 768px) {
  .message-item {
    max-width: 90%;
  }

  .control-bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 15px;
  }
}
</style>